package com.problem.heap;

import java.util.*;

/**
 *
 * 973
 * https://leetcode-cn.com/problems/k-closest-points-to-origin/
 */
public class KClosest {
    //我们有一个由平面上的点组成的列表 points。需要从中找出 K 个距离原点 (0, 0) 最近的点。
    //
    //（这里，平面上两点之间的距离是欧几里德距离。）
    //
    //你可以按任何顺序返回答案。除了点坐标的顺序之外，答案确保是唯一的。
    //
    // 
    //
    //示例 1：
    //
    //输入：points = [[1,3],[-2,2]], K = 1
    //输出：[[-2,2]]
    //解释：
    //(1, 3) 和原点之间的距离为 sqrt(10)，
    //(-2, 2) 和原点之间的距离为 sqrt(8)，
    //由于 sqrt(8) < sqrt(10)，(-2, 2) 离原点更近。
    //我们只需要距离原点最近的 K = 1 个点，所以答案就是 [[-2,2]]。
    //示例 2：
    //
    //输入：points = [[3,3],[5,-1],[-2,4]], K = 2
    //输出：[[3,3],[-2,4]]
    //（答案 [[-2,4],[3,3]] 也会被接受。）
    // 
    //
    //提示：
    //
    //1 <= K <= points.length <= 10000
    //-10000 < points[i][0] < 10000
    //-10000 < points[i][1] < 10000

    public int[][] kClosest(int[][] points, int K) {

        double[] l = new double[points.length];

        Map<Double,List<int[]>> m = new HashMap<>();
        for (int i=0;i<points.length;i++) {
            l[i] = Math.sqrt((points[i][0]*points[i][0] +points[i][1]*points[i][1]));
            List<int[]> ll = m.get(l[i]);
            if (ll == null) {
                ll = new ArrayList<>();
                m.put(l[i],ll);
            }
            ll.add(points[i]);
        }
        Arrays.sort(l);

        int[][] res = new int[K][];
        int n=0;
        retry:
        for (int i=0;i<K;i++) {
            List<int[]> li = m.get(l[i]);
            for (int[] a : li) {
                res[n] = a;
                if (n == K-1) {
                    break retry;
                }
                n++;
            }

        }
        return res;
    }

    public static void main(String[] args) {
        //[[1,3],[-2,2]]
        int[][] points = new int[3][];
        int[] a = new int[]{3,3};
        int[] b = new int[]{5,-1};
        int[] c = new int[]{-2,4};
        points[0] = a;
        points[1] = b;
        points[2] = c;

        System.out.println(new KClosest().kClosest(points,2));
    }

    public int[][] xxx(int[][] points,int K) {
        Queue<int[]> priorityQueue = new PriorityQueue<>(K, (o1, o2) -> o1[0] * o1[0] + o1[1] * o1[1] - o2[0] * o2[0] - o2[1] * o2[1]);
        for (int[] point : points) {
            priorityQueue.add(point);
        }
        int[][] result = new int[K][2];
        for (int i = 0; i < K; i++) {
            result[i] = priorityQueue.poll();
        }
        return result;
    }
}
